type GetValueType<P> = P extends Promise<infer Value> ? Value : never

type Test1 = GetValueType<Promise<'abin'>>

// 数组

type GetFirst<Arr extends unknown[]> = Arr extends [infer First, ...unknown[]] ? First : never

type Test2 = GetFirst<[1, 2, 4]>

type GetLast<Arr extends unknown[]> = Arr extends [...unknown[], infer Last] ? Last : never

type Test3 = GetLast<[1, 2, 4]>

type PopArr<Arr extends unknown[]> = Arr extends [] ? []
    : Arr extends [...infer Rest, unknown] ? Rest
    : never

type Test4 = PopArr<[1, 2, 4]>

type ShfitArr<Arr extends unknown[]> = Arr extends [] ? []
    : Arr extends [unknown, ...infer Rest] ? Rest
    : never

type Test5 = ShfitArr<[1, 2, 4]>

// 字符串

type StartWith<Str extends string, Prefix extends string> = Str extends `${Prefix}${string}` ? true : false

type Test6 = StartWith<'abin is good', 'abin'>

type ReplaceStr<Str extends string, From extends string, To extends string> = Str extends `${infer Prefix}${From}${infer Suffix}`
    ? `${Prefix}${To}${Suffix}` : never

type Test7 = ReplaceStr<'abinabcdef', 'abc', 'cba'>

type TrimRight<Str extends string> = Str extends `${infer Rest}${' ' | '\n' | '\t'}` ? TrimRight<Rest> : Str

type Test8 = TrimRight<'ABIN    '>

// 函数

type GetParamters<Func extends Function> = Func extends (...args: infer Args) => unknown ? Args : never

type Test9 = GetParamters<(name: string, age: number) => void>

type GetReturnType<Func extends Function> = Func extends (...args) => infer ReturnType ? ReturnType : never

type Test10 = GetReturnType<(name: string, age: number) => string[]>

type GetThisParameterType<T> = T extends (this: infer ThisType, ...args: any[]) => any ? ThisType : unknown

class Dong {
    name: string
    hello(this: Dong) {

    }
}
const dong = new Dong
type Test11 = GetThisParameterType<typeof dong.hello>

// 构造器

interface Person {
    name: string
}

interface PersonConstrutor {
    new(name: string): Person
}

type GetInstanceType<T extends new (...args: any[]) => any> = T extends new (...args: any[]) => infer ReturnType ? ReturnType : never

type Test12 = GetInstanceType<PersonConstrutor>

type GetInstanceParameters<T extends new (...args: any[]) => any> = T extends new (...args: infer ParameterType) => any ? ParameterType : never

type Test13 = GetInstanceParameters<PersonConstrutor>

// 索引类型

type GetRefProps<Props> = 'ref' extends keyof Props
    ? Props extends { ref?: infer Value | undefined }
    ? Value
    : never
    : never
